#include "stdinclude.h"
#include "core/component.h"


ComponentContainer::ComponentContainer(void)
{
}


ComponentContainer::~ComponentContainer(void)
{
}



void ComponentContainer::addComponent(IComponent* component)
{	
	IComponentInterface* cifc =  component->getInterface();
	unsigned id = cifc->getInterfaceID();
	components[id] = component;
}

void ComponentContainer::removeComponent(IComponent* component)
{
	IComponentInterface* cifc =  component->getInterface();
	unsigned id = cifc->getInterfaceID();
	components.erase(id);
}
	

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



ComponentContainer2::ComponentContainer2(void)
{
}


ComponentContainer2::~ComponentContainer2(void)
{
	
  // calling unregisterComponent will cause the mStringComponentMap to
  // change so we'll accumulate all the pointers here
  std::vector<Component *> Components;

  // collect Component pointers
  for (ComponentByTypeIdLkup::iterator iter = mStringComponentMap.begin(); 
    iter != mStringComponentMap.end(); ++iter)
  {
    Components.push_back(iter->second);
  }
  
  // for all collected pointers unregister, thus cleaning the components and clearing
  // our map
  for (std::vector<Component *>::iterator iter = Components.begin();
    iter != Components.end(); ++iter)
  {
    unregisterComponent(*iter);
  }

}



void ComponentContainer2::registerComponentUnsafely(
  Component          *component,
  ComponentTypeId     typeId
)
{
  // asserting here that we have a Component with this name already registered
  assert(mStringComponentMap.find(typeId) 
    == mStringComponentMap.end());

  // store it in our table
  mStringComponentMap[typeId] = component;

  // let the component know who owns it
  //TODO component->setOwnerObject(&mGameObjectEnv);

  //add properties to the owner object
  //TODO mComponentTypes->createPropertiesForComponent(typeId, mGameObjectEnv.getPropertySet());
}

Component *ComponentContainer2::getComponentUnsafely(ComponentTypeId typeId)
{
  // find the component in the lookup
  ComponentByTypeIdLkup::iterator iter = mStringComponentMap.find(typeId);

  // make sure it exists
  if (iter != mStringComponentMap.end())
  {
    return iter->second;
  }
  else
  {
    return 0;
  }
}

// NOTE: this method is far from efficient. Unfortunately it uses a log(n) search to
// clear out the registry in the ComponentByTypeIdLkup (because we are searching through
// the values, not the keys.
void ComponentContainer2::unregisterComponent(
  Component *component, 
  bool deleteComponent)
{
  // find the component in the lookup
  for (ComponentByTypeIdLkup::iterator iter = mStringComponentMap.begin();
    iter != mStringComponentMap.end(); ++iter)
  {
    // if this is the component we want to remove
    if (iter->second == component)
    {
      //deinit if it's initted

//TODO 
/*
      if (component->getState() == GO_OBJECT_STATE_INITIALIZED)
      {
        // get it to the lowest state
        component->deinitialize();
        assert(component->getState() == GO_OBJECT_STATE_LOADED);
      }

      // remove it from the owner
      component->setOwnerObject(0);
*/

      // possibly kill it
      if (deleteComponent)
      {
        delete component;
      }

      mStringComponentMap.erase(iter);
      return;
    }
  }

  // Can't find the component's entry in the ComponentByTypeIdLkup
  assert(false);
}